package com.pet.item.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pet.api.dto.ItemDTO;
import com.pet.api.dto.OrderDetailDTO;
import com.pet.common.domain.PageDTO;
import com.pet.common.domain.Result;
import com.pet.common.domain.UserContext;
import com.pet.item.domain.po.Item;
import com.pet.item.domain.query.ItemQuery;
import com.pet.item.domain.vo.ItemDetailVO;
import com.pet.item.mapper.ItemMapper;
import com.pet.item.service.IItemService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Map;

import static com.pet.common.utils.RedisConstants.RECOMMEND_USER_KEY;

/**
 * <p>
 * 商品表 服务实现类
 * </p>
 *
 * @author Cookies
 * @since 2024-07-03
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ItemServiceImpl extends ServiceImpl<ItemMapper, Item> implements IItemService {
    private final StringRedisTemplate stringRedisTemplate;

    @Override
    public PageDTO<ItemDetailVO> getItemsListByStoreId(ItemQuery itemQuery) {
        Page<Item> page = new Page<>(itemQuery.getPageNo(), itemQuery.getPageSize());
        lambdaQuery()
                .like(StrUtil.isNotBlank(itemQuery.getKeyWord()), Item::getTitle, itemQuery.getKeyWord())
                .eq(StrUtil.isNotBlank(itemQuery.getCategory()), Item::getCategory, itemQuery.getCategory())
                .eq(Item::getStoreId, itemQuery.getStoreId())
                .page(page);
        PageDTO<ItemDetailVO> pageDTO = PageDTO.of(page, ItemDetailVO.class);
        return pageDTO;
    }

    @Override
    public PageDTO<ItemDetailVO> getHotItems() {
        Page<Item> page = new Page<>(1, 10);
        lambdaQuery()
                .orderByDesc(Item::getSold)
                .page(page);
        PageDTO<ItemDetailVO> pageDTO = PageDTO.of(page, ItemDetailVO.class);
        return pageDTO;
    }

    @Override
    public boolean addItem(Item item) {
        item.setSold(RandomUtil.randomInt(10, 100));
        item.setCommentCount(RandomUtil.randomInt(5, 50));
        item.setViews(RandomUtil.randomInt(100, 1000));
        return save(item);
    }

    @Override
    public List<ItemDTO> getItemByIds(List<Integer> ids) {
        return BeanUtil.copyToList(listByIds(ids), ItemDTO.class);
    }

    @Override
    public List<ItemDetailVO> getItemsListByCategory(String category) {
        Map<String, String> categoryMap = Map
                .of("pet", "宠物", "supply", "宠物用品", "other", "其他");
        List<Item> itemList = lambdaQuery()
                .eq(Item::getCategory, categoryMap.get(category))
                .list();
        List<ItemDetailVO> itemDetailVOList = BeanUtil.copyToList(itemList, ItemDetailVO.class);
        return itemDetailVOList;
    }

    @Override
    public void deductStock(List<OrderDetailDTO> items) {
        // 批量扣减库存
        try {
            baseMapper.saleItemBatch(items);
        } catch (Exception e) {
            log.error("扣减库存异常: {}", items);
            throw new RuntimeException("扣减库存异常, 可能是库存不足导致");
        }
    }

    @Override
    public void appendStock(List<OrderDetailDTO> items) {
        // 批量回退库存
        baseMapper.backItemBatch(items);
    }

    @Override
    public ItemDTO queryItemById(Integer id) {
        return BeanUtil.copyProperties(getById(id), ItemDTO.class);
    }

    @Override
    public Result getRecommendItems(Integer current) {
        if (current < 0 || current > 4) {
            return Result.error("推荐商品列表已经到底啦");
        }
        Integer userId = UserContext.getUser();
        String key = RECOMMEND_USER_KEY + userId;
        String idsJson = stringRedisTemplate.opsForValue().get(key);
        List<Item> itemList;
        if (StrUtil.isNotBlank(idsJson)) {
            List<Integer> ids = JSONUtil.toList(idsJson, Integer.class);
            int begin = (current - 1) * 5;
            int end = current * 5;
            ids = ids.subList(begin, end);
            String idsStr = StrUtil.join(",", ids);
            itemList = lambdaQuery()
                    .in(Item::getId, ids)
                    .last("ORDER BY FIELD(id," + idsStr + ")")
                    .list();
        } else {
            itemList = lambdaQuery()
                    .orderByDesc(Item::getViews)
                    .page(new Page<>(current, 5))
                    .getRecords();
        }
        if (itemList == null || itemList.isEmpty()) {
            return Result.success(Collections.emptyList());
        }
        return Result.success(BeanUtil.copyToList(itemList, ItemDetailVO.class));
    }
}
